#include "feature.h"


// initialize static private members
cv::BFMatcher* FeatureSift::sift_matcher_ = new cv::BFMatcher(cv::NORM_L2, false);
cv::Ptr<cv::Feature2D> FeatureSift::sift_keypt_dect_ = cv::xfeatures2d::SIFT::create();

cv::BFMatcher* FeatureBrisk::brisk_matcher_ = new cv::BFMatcher(cv::NORM_HAMMING, false);
cv::Ptr<cv::Feature2D> FeatureBrisk::brisk_keypt_dect_ = cv::BRISK::create();

// class member function for class Feature

Feature::Feature() {}
Feature::~Feature() {}

// load image from image file name
bool Feature::LoadImg(const std::string& s) {
  img_file_ = s;
  img_ = cv::imread(s);
  keypoints_.clear();
  desc_.release();
  VLOG(2) << "load image: " + s + " success: " << !img_.empty();
  return !img_.empty();
}

// load image from Feature object
bool Feature::LoadImg(const Feature& feat) {
  img_file_ = feat.img_file();
  img_ = feat.img();
  keypoints_.clear();
  desc_.release();
  return !img_.empty();
}


// derived from parent class
bool Feature::ExtractFeature(bool with_desc) {
  VLOG(2) << "extract feature with desc: " << with_desc;
  if (img_.empty()) {
    LOG(ERROR) << "img is empty: " + img_file_;
    return false;
  }

  keypt_dect_->detect(img_, keypoints_);
  VLOG(2) << "keypoint size : " << keypoints_.size();

  if (with_desc) {
    VLOG(1) << "extract feat with descriptors";
    keypt_dect_->compute(img_, keypoints_, desc_);
  }
  return true;
}

// class member function for class FeatureSift
FeatureSift::FeatureSift() { 
  matcher_ = sift_matcher_; 
  keypt_dect_ = sift_keypt_dect_;
}

FeatureSift::~FeatureSift() {}



// class member function for class FeatureBrisk
FeatureBrisk::FeatureBrisk() {
  matcher_ = brisk_matcher_;
  keypt_dect_ = brisk_keypt_dect_;
}

FeatureBrisk::~FeatureBrisk() {}



